package com.lottery.im.module.chat.ui;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.OnClick;
import com.lottery.im.MyApplication;
import com.lottery.im.R;
import com.lottery.im.api.result.entity.SingleRedPacketsReceived;
import com.lottery.im.base.BaseActivity;
import com.lottery.im.constant.Constants;
import com.lottery.im.constant.SpKeyConstant;
import com.lottery.im.module.chat.adapter.ChatAdapter;
import com.lottery.im.module.main.ui.ImagePreviewActivity;
import com.lottery.im.module.tim.message.CustomMessage;
import com.lottery.im.module.tim.message.CustomMessageType;
import com.lottery.im.module.tim.message.ImageMessage;
import com.lottery.im.module.tim.message.Message;
import com.lottery.im.module.tim.message.MessageFactory;
import com.lottery.im.module.tim.message.TextMessage;
import com.lottery.im.module.tim.message.UGCMessage;
import com.lottery.im.module.tim.message.VideoMessage;
import com.lottery.im.module.tim.message.VoiceMessage;
import com.lottery.im.module.tim.model.FriendProfile;
import com.lottery.im.module.tim.model.FriendshipInfo;
import com.lottery.im.module.tim.model.GroupInfo;
import com.lottery.im.module.tim.presenter.ChatPresenter;
import com.lottery.im.module.tim.ui.ChatInput;
import com.lottery.im.module.tim.ui.TCVideoRecordActivity;
import com.lottery.im.module.tim.ui.VoiceSendingView;
import com.lottery.im.module.tim.utils.MediaUtil;
import com.lottery.im.module.tim.utils.RecorderUtil1;
import com.lottery.im.module.tim.utils.TimFileUtil;
import com.lottery.im.module.tim.viewfeatures.ChatView;
import com.lottery.im.util.SPUtils;
import com.lottery.im.widget.dialog.GroupNotifDialogBuilder;
import com.lottery.im.widget.dialog.RedPackets1DialogBuilder;
import com.lzy.imagepicker.ImagePicker;
import com.lzy.imagepicker.bean.ImageItem;
import com.lzy.imagepicker.ui.ImageGridActivity;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.tencent.imsdk.TIMConversationType;
import com.tencent.imsdk.TIMElem;
import com.tencent.imsdk.TIMFriendshipManager;
import com.tencent.imsdk.TIMGroupMemberRoleType;
import com.tencent.imsdk.TIMImage;
import com.tencent.imsdk.TIMImageElem;
import com.tencent.imsdk.TIMImageType;
import com.tencent.imsdk.TIMMessage;
import com.tencent.imsdk.TIMMessageOfflinePushSettings;
import com.tencent.imsdk.TIMMessageStatus;
import com.tencent.imsdk.TIMUserProfile;
import com.tencent.imsdk.TIMValueCallBack;
import com.tencent.imsdk.ext.group.TIMGroupSelfInfo;
import com.tencent.imsdk.ext.message.TIMMessageDraft;
import com.tencent.imsdk.ext.message.TIMMessageExt;
import com.tencent.imsdk.ext.message.TIMMessageLocator;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 为了防止不必要的麻烦
 * 聊天界面启动一个新的 Activity
 */
public class ChatActivity extends BaseActivity implements ChatView {

  public static final String IDENTIFY_KEY = "IDENTIFY_KEY";
  public static final String TYPE_KEY = "TYPE_KEY";

  public static void navToChat(Context context, String identify, TIMConversationType type) {
    Intent intent = new Intent(context, ChatActivity.class);
    intent.putExtra(IDENTIFY_KEY, identify);
    intent.putExtra(TYPE_KEY, type);
    context.startActivity(intent);
  }

  @BindView(R.id.tv_title) TextView mTvTitle;
  @BindView(R.id.iv_profile) ImageButton mIvProfile;
  @BindView(R.id.input_panel) ChatInput input;
  @BindView(R.id.list) ListView listView;
  @BindView(R.id.voice_sending) VoiceSendingView voiceSendingView;

  private String identify;
  private TIMConversationType type;

  private List<Message> messageList = new ArrayList<>();
  private ChatAdapter adapter;
  private ChatPresenter mChatPresenter;
  private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
  private static final int IMAGE_STORE = 200;
  private static final int FILE_CODE = 300;
  private static final int IMAGE_PREVIEW = 400;
  private static final int VIDEO_RECORD = 500;
  private RecorderUtil1 recorder = new RecorderUtil1();
  private String titleStr;
  private Handler handler = new Handler();
  private boolean isOneLoad = true;
  // 拍照
  private final static int PICK_PHOTO_REQCODE = 88;
  // 图片选择
  private final static int PICK_IMAGE_REQCODE = 888;
  // 原图选择
  private final static int PICK_ORIGINAL_REQCODE = 8888;
  // 名片选择
  private final static int BUSINESSCARD_REQCODE = 99;
  // @成员选择
  private final static int MEMBER_SELECT_REQCODE = 999;
  // 发送单个红包
  private final static int SEND_SINGLE_REQCODE = 9999;
  // 发送群聊红包
  private final static int SEND_GROUP_REQCODE = 77;

  @Override protected int getLayoutResId() {
    return R.layout.activity_chat;
  }

  @Override protected void initPresenter() {
    initView();
  }

  @SuppressLint("ClickableViewAccessibility") private void initView() {

    //getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
    identify = getIntent().getStringExtra(IDENTIFY_KEY);
    type = (TIMConversationType) getIntent().getSerializableExtra(TYPE_KEY);
    SPUtils.put(this, SpKeyConstant.CHAT_IDENTIFY_KEY, identify);
    if (null == mChatPresenter) {
      mChatPresenter = new ChatPresenter(this, identify, type);
    }
    input.setChatView(this);
    messageList.clear();
    adapter = new ChatAdapter(mActivity, R.layout.item_message, messageList);
    adapter.setOnResendClickListener(position -> resend(position));
    adapter.setOnHongBaoClickListener((id, note) -> {
      if (type == TIMConversationType.C2C) {
        mChatPresenter.receiveSingleRedPackets(mActivity, id, note);
      } else {
        mChatPresenter.receiveRedPackets(mActivity, id, note);
      }
    });
    adapter.setOnImageClickListener(url -> {
      ArrayList<String> urls = new ArrayList<>();
      for (Message message : messageList) {
        if (message instanceof ImageMessage) {
          try {
            TIMImageElem e = (TIMImageElem) message.getMessage().getElement(0);
            for (final TIMImage image : e.getImageList()) {
              if (image.getType() == TIMImageType.Original) {
                urls.add(image.getUrl());
              }
            }
          } catch (Exception e) {
          }
        }
      }
      int position = 0;
      for (int i = 0; i < urls.size(); i++) {
        if (url.equals(urls.get(i))) {
          position = i;
          break;
        }
      }
      ImagePreviewActivity.create(mActivity, ImagePreviewActivity.URL_TYPE, position, urls);
    });
    listView.setAdapter(adapter);
    listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
    listView.setOnTouchListener((v, event) -> {
      switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          input.setInputMode(ChatInput.InputMode.NONE);
          break;
      }
      return false;
    });
    // 滑动顶部 加载更多
    listView.setOnScrollListener(new AbsListView.OnScrollListener() {
      private int firstItem;

      @Override
      public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE && firstItem == 0) {
          //如果拉到顶端读取更多消息
          mChatPresenter.getMessage(
              messageList.size() > 0 ? messageList.get(0).getMessage() : null);
        }
      }

      @Override
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
          int totalItemCount) {
        firstItem = firstVisibleItem;
      }
    });
    // 注册item长按监听
    registerForContextMenu(listView);

    switch (type) {
      case C2C:
        mIvProfile.setImageDrawable(getResources().getDrawable(R.drawable.icon_profile));
        if (FriendshipInfo.getInstance().isFriend(identify)) {
          FriendProfile profile = FriendshipInfo.getInstance().getProfile(identify);
          mTvTitle.setText(titleStr = profile == null ? identify : profile.getName());
        } else {
          mTvTitle.setText(titleStr = identify);
          TIMFriendshipManager.getInstance().getUsersProfile(Collections.singletonList(identify),
              new TIMValueCallBack<List<TIMUserProfile>>() {
                @Override public void onError(int i, String s) {
                }

                @Override public void onSuccess(List<TIMUserProfile> timUserProfiles) {
                  if (null != timUserProfiles && timUserProfiles.size() > 0) {
                    if (null != mActivity && !mActivity.isFinishing() && null != mTvTitle) {
                      mTvTitle.setText(timUserProfiles.get(0).getNickName());
                    }
                  }
                }
              });
        }
        input.isGroup(false);
        break;
      case Group:
        mIvProfile.setImageDrawable(getResources().getDrawable(R.drawable.icon_qgl));
        mTvTitle.setText(GroupInfo.getInstance().getGroupName(identify));
        // 只有群主/群管理员才显示发送名片
        if (GroupInfo.getInstance().getRole(identify) != TIMGroupMemberRoleType.Admin &&
            GroupInfo.getInstance().getRole(identify) != TIMGroupMemberRoleType.Owner) {
          input.isGroup(false);
        }
        mChatPresenter.getNotification(identify);
        mChatPresenter.getGroupUserOnline(identify);
        mChatPresenter.getSelfInfo(identify);
        break;
    }
    mChatPresenter.start();
  }

  @OnClick({ R.id.iv_back, R.id.iv_profile }) public void onViewClicked(View view) {
    switch (view.getId()) {
      case R.id.iv_back:
        finish();
        break;
      case R.id.iv_profile:
        switch (type) {
          case C2C:
            NewFragmentActivity.create(mActivity, NewFragmentActivity.FragmentInfoType.Other,
                identify);
            break;
          case Group:
            // 群
            NewFragmentActivity.create(mActivity, NewFragmentActivity.FragmentInfoType.Group,
                identify);
            break;
        }
        break;
    }
  }

  /**
   * 显示消息
   */
  @Override public void showMessage(TIMMessage message) {
    if (message == null) {
      adapter.notifyDataSetChanged();
    } else {
      Message mMessage = MessageFactory.getMessage(message);
      if (mMessage != null) {
        if (mMessage instanceof CustomMessage) {
          CustomMessage.Type messageType = ((CustomMessage) mMessage).getType();
          switch (messageType) {
            case TYPING:
              mTvTitle.setText("对方正在输入…");
              handler.removeCallbacks(resetTitle);
              handler.postDelayed(resetTitle, 3000);
              break;
            default:
              break;
          }
        } else {
          if (messageList.size() == 0) {
            mMessage.setHasTime(null);
          } else {
            mMessage.setHasTime(messageList.get(messageList.size() - 1).getMessage());
          }
          messageList.add(mMessage);
          adapter.notifyDataSetChanged();
          listView.setSelection(ListView.FOCUS_DOWN);
        }
      }
    }
  }

  /**
   * 显示消息
   */
  @Override public void showMessage(List<TIMMessage> messages) {
    int newMsgNum = 0;
    for (int i = 0; i < messages.size(); ++i) {
      Message mMessage = MessageFactory.getMessage(messages.get(i));
      if (mMessage == null || messages.get(i).status() == TIMMessageStatus.HasDeleted) continue;
      if (mMessage instanceof CustomMessage && (
          ((CustomMessage) mMessage).getType() == CustomMessage.Type.TYPING ||
              ((CustomMessage) mMessage).getType() == CustomMessage.Type.INVALID)) {
        continue;
      }
      ++newMsgNum;
      if (i != messages.size() - 1) {
        mMessage.setHasTime(messages.get(i + 1));
        messageList.add(0, mMessage);
      } else {
        mMessage.setHasTime(null);
        messageList.add(0, mMessage);
      }
    }
    adapter.notifyDataSetChanged();
    if (isOneLoad) {
      listView.setSelection(ListView.FOCUS_DOWN);
      isOneLoad = false;
    } else {
      listView.setSelection(newMsgNum);
    }
  }

  @Override public void showRevokeMessage(TIMMessageLocator timMessageLocator) {
    for (Message msg : messageList) {
      TIMMessageExt ext = new TIMMessageExt(msg.getMessage());
      if (ext.checkEquals(timMessageLocator)) {
        adapter.notifyDataSetChanged();
      }
    }
  }

  /**
   * 清除所有消息，等待刷新
   */
  @Override
  public void clearAllMessage() {
    messageList.clear();
  }

  /**
   * 发送消息成功
   *
   * @param message 返回的消息
   */
  @Override
  public void onSendMessageSuccess(TIMMessage message) {
    showMessage(message);
  }

  /**
   * 发送消息失败
   *
   * @param code 返回码
   * @param desc 返回描述
   */
  @Override
  public void onSendMessageFail(int code, String desc, TIMMessage message) {
    long id = message.getMsgUniqueId();
    for (Message msg : messageList) {
      if (msg.getMessage().getMsgUniqueId() == id) {
        switch (code) {
          case 80001:
            //发送内容包含敏感词
            msg.setDesc("内容含有敏感词");
            adapter.notifyDataSetChanged();
            break;
          case 10017:
            showToast("因被禁言而不能发送消息");
            break;
        }
      }
    }

    adapter.notifyDataSetChanged();
  }

  /**
   * 发送图片消息
   */
  @Override
  public void sendImage() {

    new RxPermissions(this).request(Manifest.permission.CAMERA,
        Manifest.permission.READ_EXTERNAL_STORAGE)
        .subscribe(new Observer<Boolean>() {
          @Override public void onSubscribe(Disposable d) {

          }

          @Override public void onNext(Boolean aBoolean) {
            if (aBoolean) {
              ImagePicker.getInstance().setMultiMode(false);
              ImagePicker.getInstance().setShowCamera(false);  //显示拍照按钮
              ImagePicker.getInstance().setCrop(false);        //允许裁剪（单选才有效）
              Intent intent = new Intent(mActivity, ImageGridActivity.class);
              startActivityForResult(intent, PICK_IMAGE_REQCODE);
            } else {
              showToast("你已拒绝访问相册和拍照权限～");
            }
          }

          @Override public void onError(Throwable e) {

          }

          @Override public void onComplete() {

          }
        });
  }

  /**
   * 发送照片消息
   */
  @Override
  public void sendPhoto() {
    new RxPermissions(this).request(Manifest.permission.CAMERA,
        Manifest.permission.READ_EXTERNAL_STORAGE)
        .subscribe(new Observer<Boolean>() {
          @Override public void onSubscribe(Disposable d) {

          }

          @Override public void onNext(Boolean aBoolean) {
            if (aBoolean) {
              ImagePicker.getInstance().setMultiMode(false);
              ImagePicker.getInstance().setCrop(false);
              Intent intent = new Intent(mActivity, ImageGridActivity.class);
              intent.putExtra(ImageGridActivity.EXTRAS_TAKE_PICKERS, true); // 是否是直接打开相机
              startActivityForResult(intent, PICK_PHOTO_REQCODE);
            } else {
              showToast("你已拒绝访问相册和拍照权限～");
            }
          }

          @Override public void onError(Throwable e) {

          }

          @Override public void onComplete() {

          }
        });
  }

  /**
   * 发送文本消息
   */
  @Override
  public void sendText() {
    Message message = new TextMessage(input.getText());
    mChatPresenter.sendMessage(message.getMessage());
    input.setText("");
  }

  /**
   * 发送文件
   */
  @Override
  public void sendFile() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("*/*");
    startActivityForResult(intent, FILE_CODE);
  }

  /*
   *  发送红包
   * */
  @Override public void sendRedPackets() {
    if (type == TIMConversationType.C2C) {
      SendSingleRedPacketsActivity.create(this, identify, SEND_SINGLE_REQCODE);
    } else {
      SendGroupRedPacketsActivity.create(this, identify, SEND_GROUP_REQCODE);
    }
  }

  /*
   *  发送名片
   * */
  @Override public void sendBusinessCard() {
    SelectBusinessCardActivity.create(this, identify, BUSINESSCARD_REQCODE);
  }

  /*
   * 发送自定义表情
   * */
  @Override public void sendCustonFace(String faceText) {
    if (faceText.endsWith(".png") || faceText.endsWith(".gif")) {
      faceText = faceText.substring(0, faceText.length() - 4);
      Message message = new TextMessage(faceText);
      TIMMessage imgMsg = message.getMessage();
      TIMMessageOfflinePushSettings settings = new TIMMessageOfflinePushSettings();
      settings.setEnabled(true);
      StringBuffer des = new StringBuffer();
      des.append(MyApplication.getInstance().getUserInfo().getUserName());
      if (type == TIMConversationType.Group) {
        des.append("(" + GroupInfo.getInstance().getGroupName(identify) + ")");
      }
      des.append(":");
      des.append("[表情]");
      settings.setDescr(des.toString());
      imgMsg.setOfflinePushSettings(settings);
      mChatPresenter.sendMessage(imgMsg);
    } else {
      if (faceText.startsWith(CustomMessageType.CUSTOMFACE_TYPE)) {
        String path =
            faceText.substring(CustomMessageType.CUSTOMFACE_TYPE.length(), faceText.length());
        if (TimFileUtil.isCacheFileExist(path + ".jpg")) {
          Message message = new ImageMessage(TimFileUtil.getCacheFilePath(path + ".jpg"), true);
          mChatPresenter.sendMessage(message.getMessage());
        }
      }
    }
  }

  /**
   * 开始发送语音消息
   */
  @Override
  public void startSendVoice() {
    voiceSendingView.setVisibility(View.VISIBLE);
    voiceSendingView.showRecording();
    recorder.startRecording();
  }

  /*
   * 取消发送提示
   * */
  @Override public void wantToCancel(boolean isWant) {
    voiceSendingView.setVisibility(View.VISIBLE);
    voiceSendingView.wantToCancel(isWant);
  }

  /**
   * 结束发送语音消息
   */
  @Override
  public void endSendVoice(boolean isCancel) {
    voiceSendingView.release();
    voiceSendingView.setVisibility(View.GONE);
    recorder.stopRecording();
    if (!isCancel) {
      if (recorder.getTimeInterval() < 1) {
        showToast(R.string.chat_audio_too_short);
      } else if (recorder.getTimeInterval() > 60) {
        showToast(R.string.chat_audio_too_long);
      } else {
        Message message = new VoiceMessage(recorder.getTimeInterval(), recorder.getFilePath());
        mChatPresenter.sendMessage(message.getMessage());
      }
    }
  }

  /**
   * 发送小视频消息
   *
   * @param fileName 文件名
   */
  @Override
  public void sendVideo(String fileName) {
    Message message = new VideoMessage(fileName);
    mChatPresenter.sendMessage(message.getMessage());
  }

  /**
   * 结束发送语音消息
   */
  @Override
  public void cancelSendVoice() {

  }

  /**
   * 正在发送
   */
  @Override
  public void sending() {
    if (type == TIMConversationType.C2C) {
      Message message = new CustomMessage(CustomMessage.Type.TYPING);
      mChatPresenter.sendOnlineMessage(message.getMessage());
    }
  }

  /**
   * 显示草稿
   */
  @Override
  public void showDraft(TIMMessageDraft draft) {
    input.getText().append(TextMessage.getString(draft.getElems(), mActivity));
  }

  /**
   * 开启录制小视频
   */
  @Override
  public void videoAction() {

    new RxPermissions(this).request(Manifest.permission.CAMERA,
        Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO)
        .subscribe(new Observer<Boolean>() {
          @Override public void onSubscribe(Disposable d) {

          }

          @Override public void onNext(Boolean aBoolean) {
            if (aBoolean) {
              Intent intent = new Intent(mActivity, TCVideoRecordActivity.class);
              startActivityForResult(intent, VIDEO_RECORD);
            } else {
              showToast("你已拒绝访问相机或录音权限，无法使用该功能");
            }
          }

          @Override public void onError(Throwable e) {

          }

          @Override public void onComplete() {

          }
        });
  }

  /**
   * @param content 群公告弹窗
   */
  @Override public void showGroupNotification(String content) {
    if (content.contains(Constants.NOTICE_SEPARATE)) {
      GroupNotifDialogBuilder.getInstance(mActivity)
          .setTitle(content.substring(0, content.indexOf(Constants.NOTICE_SEPARATE)))
          .setContent(content.substring(
              content.indexOf(Constants.NOTICE_SEPARATE) + Constants.NOTICE_SEPARATE.length(),
              content.length()))
          .show();
    } else {
      GroupNotifDialogBuilder.getInstance(mActivity)
          .setTitle("")
          .setContent(content).show();
    }
  }

  /**
   * 显示群在线人数情况
   *
   * @param onlineNum 在线人数
   * @param memberNum 总人数
   */
  @Override public void showOnlineNum(int onlineNum, int memberNum) {
    mTvTitle.setText(
        GroupInfo.getInstance().getGroupName(identify) + "(" + onlineNum + "/" + memberNum + ")");
  }

  @Override public void updateGroup(String groupId) {
    if (groupId.equals(identify)) finish();
  }

  @Override public void getSelfGroupProfile(TIMGroupSelfInfo timGroupSelfInfo) {
    if (TextUtils.isEmpty(timGroupSelfInfo.getNameCard())) {
      adapter.setSelfGroupCardName(MyApplication.getInstance().getUserInfo().getUserName());
    } else {
      adapter.setSelfGroupCardName(timGroupSelfInfo.getNameCard());
    }
  }

  @Override public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (type == TIMConversationType.Group) {
      if (s.toString().endsWith("@") && count == 1) {
        SelectMemberActivity.create(this, identify, MEMBER_SELECT_REQCODE);
      }
    }
  }

  /**
   * 领取单个红包成功
   */
  @Override
  public void receiveRedPacketsSuce(SingleRedPacketsReceived singleRedPacketsReceived,
      String note) {

    String ids = (String) SPUtils.get(this, SpKeyConstant.REDPACKETS_ID_KEY, "");

    String newId = singleRedPacketsReceived.getRedPacketsId() + "_" + MyApplication.getInstance()
        .getUserInfo()
        .getUserId();

    if (!Arrays.asList(ids.split(","))
        .contains(newId)) {
      SPUtils.put(this, SpKeyConstant.REDPACKETS_ID_KEY,
          ids + "," + newId);
      adapter.notifyDataSetChanged();
    }
    if (singleRedPacketsReceived.getReceivedStatus() == 0) {
      // 红包已被领完
      RedPackets1DialogBuilder.getInstance(this).setContent(singleRedPacketsReceived,
          v -> NewFragmentActivity.create(ChatActivity.this, type, singleRedPacketsReceived, note))
          .show();
    } else if (singleRedPacketsReceived.getReceivedStatus() == 1) {
      //  领取成功
      RedPackets1DialogBuilder.getInstance(this).setSucContent(singleRedPacketsReceived,
          v -> NewFragmentActivity.create(ChatActivity.this, type, singleRedPacketsReceived, note))
          .show();
    } else if (singleRedPacketsReceived.getReceivedStatus() == 2) {
      //  该红包已领过
      NewFragmentActivity.create(ChatActivity.this, type, singleRedPacketsReceived, note);
    } else if (singleRedPacketsReceived.getReceivedStatus() == 3) {
      //  该红包已过期
      RedPackets1DialogBuilder.getInstance(this)
          .setTip("抱歉\n红包已过期")
          .setContent(singleRedPacketsReceived,
              v -> NewFragmentActivity.create(ChatActivity.this, type, singleRedPacketsReceived,
                  note))
          .show();
    }
  }

  /**
   * @param position 重新发送
   */
  private void resend(int position) {
    Message message = messageList.get(position);
    messageList.remove(message);
    mChatPresenter.sendMessage(message.getMessage());
  }

  @Override
  public void onCreateContextMenu(ContextMenu menu, View v,
      ContextMenu.ContextMenuInfo menuInfo) {
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
    Message message = messageList.get(info.position);

    String content = null;
    if (message instanceof TextMessage) {
      List<TIMElem> elems = new ArrayList<>();
      for (int i = 0; i < message.getMessage().getElementCount(); ++i) {
        elems.add(message.getMessage().getElement(i));
      }
      SpannableStringBuilder stringBuilder = TextMessage.getString(elems, this);
      content = stringBuilder.toString();
    }

    // 文字消息，并且不是自定义表情、名片、红包 可以复制
    if (!TextUtils.isEmpty(content)) {
      if (!content.startsWith(CustomMessageType.CUSTOMFACE_TYPE)
          && !content.startsWith(CustomMessageType.BUSINESSCARD_TYPE)
          && !content.startsWith(CustomMessageType.HONGBAO_TYPE)
          ) {
        menu.add(0, 1, Menu.NONE, "复制");
      }
    }

    // 图片消息 并且未保存过 支持保存到表情
    if (message instanceof ImageMessage) {
      if (message instanceof ImageMessage) {
        try {
          TIMImageElem e = (TIMImageElem) message.getMessage().getElement(0);
          for (final TIMImage image : e.getImageList()) {
            if (image.getType() == TIMImageType.Original) {

              String path = image.getUuid();
              String facePaths =
                  (String) SPUtils.get(this, SpKeyConstant.FACE_IMGAE_PATH_KEY, "");
              if (TextUtils.isEmpty(facePaths)) {
                menu.add(0, 5, Menu.NONE, "添加到表情");
              } else {
                if (!Arrays.asList(facePaths.split(",")).contains(path)) {
                  menu.add(0, 5, Menu.NONE, "添加到表情");
                }
              }
              break;
            }
          }
        } catch (Exception e) {
        }
      }
    }

    // 语音消息 切换 听筒扬声器模式
    if (message instanceof VoiceMessage) {
      boolean isPhone = (boolean) SPUtils.get(this, SpKeyConstant.SPEAKERPHONE_KEY, false);
      if (isPhone) {
        menu.add(0, 6, Menu.NONE, "使用扬声器模式");
      } else {
        menu.add(0, 6, Menu.NONE, "使用听筒模式");
      }
    }

    menu.add(0, 2, Menu.NONE, "删除");
    if (message.isSendFail()) {
      menu.add(0, 3, Menu.NONE, "重新发送");
    } else if (message.getMessage().isSelf()) {
      long sendTime = message.getMessage().timestamp();
      long currentTime = System.currentTimeMillis();
      if ((currentTime / 1000 - sendTime) < 120) {
        // 两分钟内的消息才可以撤回
        menu.add(0, 4, Menu.NONE, "撤回");
      }
    }

    //if (message instanceof ImageMessage || message instanceof FileMessage) {
    //  menu.add(0, 3, Menu.NONE, getString(R.string.chat_save));
    //}
  }

  @Override
  public boolean onContextItemSelected(MenuItem item) {
    AdapterView.AdapterContextMenuInfo info =
        (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    Message message = messageList.get(info.position);
    switch (item.getItemId()) {
      case 1:
        // 复制
        if (message instanceof TextMessage) {
          List<TIMElem> elems = new ArrayList<>();
          for (int i = 0; i < message.getMessage().getElementCount(); ++i) {
            elems.add(message.getMessage().getElement(i));
          }
          SpannableStringBuilder stringBuilder = TextMessage.getString(elems, this);
          if (!TextUtils.isEmpty(stringBuilder.toString())) {
            //获取剪贴板管理器：
            ClipboardManager cm = (ClipboardManager) getSystemService(
                Context.CLIPBOARD_SERVICE);
            // 创建普通字符型ClipData
            ClipData mClipData = ClipData.newPlainText(stringBuilder.toString(), stringBuilder);
            // 将ClipData内容放到系统剪贴板里。
            cm.setPrimaryClip(mClipData);
          }
        }
        break;
      case 2:
        // 删除
        message.remove();
        messageList.remove(info.position);
        adapter.notifyDataSetChanged();
        break;
      case 3:
        // 重新发送
        messageList.remove(message);
        mChatPresenter.sendMessage(message.getMessage());
        break;
      case 4:
        // 撤回
        mChatPresenter.revokeMessage(message.getMessage());
        break;
      case 5:
        message.save();
        if (message instanceof ImageMessage) {
          try {
            TIMImageElem e = (TIMImageElem) message.getMessage().getElement(0);
            for (final TIMImage image : e.getImageList()) {
              if (image.getType() == TIMImageType.Original) {
                String path = image.getUuid();
                String facePaths =
                    (String) SPUtils.get(this, SpKeyConstant.FACE_IMGAE_PATH_KEY, "");
                if (TextUtils.isEmpty(facePaths)) {
                  SPUtils.put(this, SpKeyConstant.FACE_IMGAE_PATH_KEY, path);
                } else {
                  SPUtils.put(this, SpKeyConstant.FACE_IMGAE_PATH_KEY, facePaths + "," + path);
                }
                input.addImgFace();
              }
            }
          } catch (Exception e) {
          }
        }
        break;
      case 6:
        boolean isPhone = (boolean) SPUtils.get(this, SpKeyConstant.SPEAKERPHONE_KEY, false);
        SPUtils.put(this, SpKeyConstant.SPEAKERPHONE_KEY, !isPhone);
        break;

      default:
        break;
    }
    return super.onContextItemSelected(item);
  }

  /**
   * @param data onActivityResult
   */
  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == Activity.RESULT_OK) {
      if (requestCode == VIDEO_RECORD) {
        // 拍摄小视频完成 返回
        String videoPath = data.getStringExtra("videoPath");
        String coverPath = data.getStringExtra("coverPath");
        long duration = data.getLongExtra("duration", 0);
        Message message = new UGCMessage(videoPath, coverPath, duration);
        mChatPresenter.sendMessage(message.getMessage());
      } else if (requestCode == PICK_ORIGINAL_REQCODE) {
        // 选择是否原图 返回
        String path = data.getStringExtra(ChooseOriginalImageActivity.PATH_KEY);
        boolean isOri = data.getBooleanExtra(ChooseOriginalImageActivity.ORIGINAL_KEY, false);
        Message message = new ImageMessage(path, isOri);
        mChatPresenter.sendMessage(message.getMessage());
      } else if (requestCode == BUSINESSCARD_REQCODE) {
        // 名片选择完成
        ArrayList<String> ids =
            data.getStringArrayListExtra(SelectBusinessCardActivity.SELECT_IDENTIFYS_KEY);
        for (String id : ids) {
          Message message = new TextMessage(CustomMessageType.BUSINESSCARD_TYPE + id);
          TIMMessage mpMsg = message.getMessage();
          TIMMessageOfflinePushSettings settings = new TIMMessageOfflinePushSettings();
          settings.setEnabled(true);
          StringBuffer des = new StringBuffer();
          des.append(MyApplication.getInstance().getUserInfo().getUserName());
          if (type == TIMConversationType.Group) {
            des.append("(" + GroupInfo.getInstance().getGroupName(identify) + ")");
          }
          des.append(":");
          des.append("[名片]");
          settings.setDescr(des.toString());
          mpMsg.setOfflinePushSettings(settings);
          mChatPresenter.sendMessage(mpMsg);
        }
      } else if (requestCode == MEMBER_SELECT_REQCODE) {
        // @群成员返回
        String nameCaed = data.getStringExtra(SelectMemberActivity.SELECT_NAME_KEY);
        input.getText().append(nameCaed + " ");
      } else if (requestCode == SEND_SINGLE_REQCODE) {
        // 发送单个红包返回
        String id = data.getStringExtra(SendSingleRedPacketsActivity.ID_KEY);
        Message message = new TextMessage(CustomMessageType.HONGBAO_TYPE + id);
        TIMMessage hbMsg = message.getMessage();
        TIMMessageOfflinePushSettings settings = new TIMMessageOfflinePushSettings();
        settings.setEnabled(true);
        StringBuffer des = new StringBuffer();
        des.append(MyApplication.getInstance().getUserInfo().getUserName());
        if (type == TIMConversationType.Group) {
          des.append("(" + GroupInfo.getInstance().getGroupName(identify) + ")");
        }
        des.append(":");
        des.append("[红包]");
        settings.setDescr(des.toString());
        hbMsg.setOfflinePushSettings(settings);
        mChatPresenter.sendMessage(hbMsg);
      } else if (requestCode == SEND_GROUP_REQCODE) {
        // 发送群聊红包返回
        String id = data.getStringExtra(SendGroupRedPacketsActivity.ID_KEY);
        Message message = new TextMessage(CustomMessageType.HONGBAO_TYPE + id);
        TIMMessage hbMsg = message.getMessage();
        TIMMessageOfflinePushSettings settings = new TIMMessageOfflinePushSettings();
        settings.setEnabled(true);
        StringBuffer des = new StringBuffer();
        des.append(MyApplication.getInstance().getUserInfo().getUserName());
        if (type == TIMConversationType.Group) {
          des.append("(" + GroupInfo.getInstance().getGroupName(identify) + ")");
        }
        des.append(":");
        des.append("[红包]");
        settings.setDescr(des.toString());
        hbMsg.setOfflinePushSettings(settings);
        mChatPresenter.sendMessage(hbMsg);
      }
    } else if (resultCode == ImagePicker.RESULT_CODE_ITEMS) {
      if (requestCode == PICK_IMAGE_REQCODE) {
        // 选择图片完成，打开是否发送原图的界面
        ArrayList<ImageItem> images =
            (ArrayList<ImageItem>) data.getSerializableExtra(ImagePicker.EXTRA_RESULT_ITEMS);
        ChooseOriginalImageActivity.create(mActivity, images.get(0).path, PICK_ORIGINAL_REQCODE);
      } else if (requestCode == PICK_PHOTO_REQCODE) {
        // 拍照完成，打开是否发送原图的界面
        ArrayList<ImageItem> images =
            (ArrayList<ImageItem>) data.getSerializableExtra(ImagePicker.EXTRA_RESULT_ITEMS);
        ChooseOriginalImageActivity.create(mActivity, images.get(0).path, PICK_ORIGINAL_REQCODE);
      }
    }
  }

  /**
   * 将标题设置为对象名称
   */
  private Runnable resetTitle = new Runnable() {
    @Override
    public void run() {
      mTvTitle.setText(titleStr);
    }
  };

  /**
   * 确保键盘是关闭的
   */
  private void hintKbOne() {
    View view = getCurrentFocus();
    if (view != null) {
      InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
      imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
    }
    //View view = getCurrentFocus();
    //if (view != null) {
    //  ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
    //      view.getWindowToken(), 0);
    //}
  }

  /**
   * @param intent singleTask 模式刷新界面
   */
  @Override protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
    initView();
  }

  @Override protected void onPause() {
    // 强制关闭键盘
    hintKbOne();
    hideKeyBoard();
    super.onPause();
    //退出聊天界面时输入框有内容，保存草稿
    if (input.getText().length() > 0) {
      TextMessage message = new TextMessage(input.getText());
      mChatPresenter.saveDraft(message.getMessage());
    } else {
      mChatPresenter.saveDraft(null);
    }
    //        RefreshEvent.getInstance().onRefresh();
    mChatPresenter.readMessages();
    MediaUtil.getInstance().stop();
  }

  @Override public void onBackPressed() {
    if (input.isShowPanel()) {
      input.setInputMode(ChatInput.InputMode.NONE);
      return;
    }
    super.onBackPressed();
  }

  @Override protected void onDestroy() {
    super.onDestroy();
    SPUtils.put(this, SpKeyConstant.CHAT_IDENTIFY_KEY, "");
    handler.removeCallbacks(resetTitle);
    mChatPresenter.stop();
  }
}
